package com.sharecar.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;

import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;

import com.android.sharecar.model.User;
import com.sharecar.db.DB;

public class UserService {
	private static UserService service;

	private UserService() {
	}

	public static UserService getInstance() {
		if (null == service) {
			service = new UserService();
		}
		return service;
	}

	/**
	 * Check an email address is already registered.
	 * @param email the address going to checked.
	 * @return true if exist, or false if not
	 */
	public boolean checkEmailIfExist(String email) {
		Connection conn = DB.getConn();
		try {
			conn.setAutoCommit(false);
		} catch (SQLException e1) {
			e1.printStackTrace();
		}

		String sql = "select userId from Users where email=? ";
		PreparedStatement pstmt = DB.prepare(conn, sql);
		try {
			pstmt.setString(1, email);
			ResultSet rs = pstmt.executeQuery();
			if (rs.next()) {
				return true;
			}
		} catch (SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		} finally {
			try {
				conn.setAutoCommit(true);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			DB.close(pstmt);
			DB.close(conn);
		}

		return false;
	}

	/**
	 * Add a user who haven't a car to db
	 * @param user the user object will be added
	 */
	public void addUserWithoutCarInfo(User user) {
		Connection conn = DB.getConn();
		try {
			conn.setAutoCommit(false);
		} catch (SQLException e1) {
			e1.printStackTrace();
		}

		String sql = "insert into Users values (null, ?, ?, ?, ?, ?, ?, ?, null, null, null)";
		PreparedStatement pstmt = DB.prepare(conn, sql);
		try {
			pstmt.setString(1, user.getEmail());
			pstmt.setString(2, user.getPassword());
			pstmt.setString(3, user.getNickName());
			pstmt.setString(4, user.getRealName());
			pstmt.setString(6, user.getMobilePhone());
			pstmt.setString(7, user.getGender());

			// Write the headpic to file system.
			UUID imgName = UUID.randomUUID();
			StringBuilder filePathBuilder = new StringBuilder();
			filePathBuilder.append("headpics/");
			filePathBuilder.append(imgName);
			filePathBuilder.append(".jpg");

			FileOutputStream fos = new FileOutputStream(
					filePathBuilder.toString());
			Bitmap headPic = user.getHeadPicture();
			headPic.compress(CompressFormat.JPEG, 100, fos);
			fos.flush();
			fos.close();

			pstmt.setString(5, filePathBuilder.toString());

			pstmt.executeUpdate();
			conn.commit();
		} catch (SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				conn.setAutoCommit(true);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			DB.close(pstmt);
			DB.close(conn);
		}
	}

	/**
	 * Update user's car info
	 * @param id user's userId
	 */
	public void updateCarInfo(User user) {
		Connection conn = DB.getConn();
		try {
			conn.setAutoCommit(false);
		} catch (SQLException e1) {
			e1.printStackTrace();
		}

		String sql = "update Users set carStyle=?, carId=?, carColor=? where userId=?";
		PreparedStatement pstmt = DB.prepare(conn, sql);
		try {
			pstmt.setString(1, user.getCarStyle());
			pstmt.setString(2, user.getCarId());
			pstmt.setString(3, user.getColor());
			pstmt.setInt(4, user.getUserId());

			pstmt.executeUpdate();
			conn.commit();
		} catch (SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		} finally {
			try {
				conn.setAutoCommit(true);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			DB.close(pstmt);
			DB.close(conn);
		}

	}

	/**
	 * Get a user's info for ta's comments, which includes user's headpic
	 * and nickname...
	 * @param id  userId
	 * @return user object contains the info
	 */
	public User getUserForCommentById(int id) {
		User user = new User();
		File headPicFile;
		FileInputStream fis;
		Connection conn = DB.getConn();
		try {
			conn.setAutoCommit(false);
		} catch (SQLException e1) {
			e1.printStackTrace();
		}

		String sql = "select nickName, headPicPath from Users where userId=? ";
		PreparedStatement pstmt = DB.prepare(conn, sql);
		try {
			pstmt.setInt(1, id);
			ResultSet rs = pstmt.executeQuery();
			if (rs.next()) {
				user.setUserId(id);

				// Here we need to decode a picture to android bitmap,
				// watch out these code..
				headPicFile = new File(rs.getString("headPicPath"));
				fis = new FileInputStream(headPicFile);
				Bitmap headPic = BitmapFactory.decodeStream(fis);

				user.setHeadPicture(headPic);
				user.setNickName(rs.getString("nickName"));

				fis.close();
			}
		} catch (SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				conn.setAutoCommit(true);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			DB.close(pstmt);
			DB.close(conn);
		}

		return user;
	}
}
